package com.zhangxin.aiInterview.service.impl;

import cn.hutool.json.JSONUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.zhangxin.aiInterview.common.ErrorCode;
import com.zhangxin.aiInterview.exception.BusinessException;
import com.zhangxin.aiInterview.manager.work_flow.hr_interview_analyze.HrInterviewAnalyze;
import com.zhangxin.aiInterview.manager.work_flow.hr_interview_analyze.model.HrInterviewAnalysisData;
import com.zhangxin.aiInterview.manager.python_api.PythonApi;
import com.zhangxin.aiInterview.manager.redis.audio_emotion.DeleteAudioEmotion;
import com.zhangxin.aiInterview.manager.redis.audio_emotion.GetAudioEmotion;
import com.zhangxin.aiInterview.manager.redis.audio_speed.DeleteAudioSpeed;
import com.zhangxin.aiInterview.manager.redis.audio_speed.GetAudioSpeeds;
import com.zhangxin.aiInterview.manager.redis.audio_speed.model.AudioSpeedEntry;
import com.zhangxin.aiInterview.mapper.HrInterviewMapper;
import com.zhangxin.aiInterview.model.dto.interview.AnalyzeHrInterviewRequest;
import com.zhangxin.aiInterview.model.entity.*;
import com.zhangxin.aiInterview.model.enums.AnalyzeStatusEnum;
import com.zhangxin.aiInterview.model.enums.IsFullInterviewEnum;
import com.zhangxin.aiInterview.service.*;
import com.zhangxin.aiInterview.utils.BodyActionManager;
import com.zhangxin.aiInterview.utils.FaceActionManager;
import com.zhangxin.aiInterview.utils.FaceEmotionManager;
import com.zhangxin.aiInterview.utils.StressManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.transaction.support.TransactionTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.concurrent.CompletableFuture;

import static com.zhangxin.aiInterview.constant.PythonConstant.python_base_url_http;

/**
 * @author ZX
 * @description 针对表【hr_interview(hr面试记录)】的数据库操作Service实现
 * @createDate 2025-05-18 15:49:13
 */
@Service
public class HrInterviewServiceImpl extends ServiceImpl<HrInterviewMapper, HrInterview>
        implements HrInterviewService {
    @Resource
    private UserService userService;
    @Resource
    private HrInterviewContentService hrInterviewContentService;
    @Resource
    private GetAudioSpeeds getAudioSpeeds;
    @Resource
    private GetAudioEmotion getAudioEmotion;
    @Resource
    private FaceActionManager faceActionManager;
    @Resource
    private BodyActionManager bodyActionManager;
    @Resource
    private FaceEmotionManager faceEmotionManager;
    @Resource
    private DeleteAudioEmotion deleteAudioEmotion;
    @Resource
    private DeleteAudioSpeed deleteAudioSpeed;
    @Resource
    private HrInterviewAnalyzeResultService hrInterviewAnalyzeResultService;
    @Resource
    private FullProcessInterviewService fullProcessInterviewService;
    @Resource
    private FullProcessAnalyzeResultService fullProcessAnalyzeResultService;
    @Resource
    private CompanyService companyService;
    @Resource
    private StressManager stressManager;
    @Resource
    private PythonApi pythonApi;
    @Resource
    private TransactionTemplate transactionTemplate;

    /**
     * 分析hr面试
     *
     * @param analyzeHrInterviewRequest
     * @param request
     * @param isFull
     * @param fullInterviewId
     */
    @Override
    @Transactional
    public void analyzeHrInterview(AnalyzeHrInterviewRequest analyzeHrInterviewRequest, HttpServletRequest request, Boolean isFull, Long fullInterviewId) {
        Long hrInterviewId = analyzeHrInterviewRequest.getHrInterviewId();
        Long userId = userService.getLoginUser(request).getId();
        //更新面试状态和时间
        boolean updateDuration = lambdaUpdate()
                .eq(HrInterview::getId, hrInterviewId)
                .set(HrInterview::getInterviewStatus, AnalyzeStatusEnum.ANALYZING.getValue())
                .set(HrInterview::getInterviewDuration, analyzeHrInterviewRequest.getInterviewDuration())
                .update();
        if (!updateDuration) throw new BusinessException(ErrorCode.OPERATION_ERROR, "更新面试时间失败");

        List<AnalyzeHrInterviewRequest.InterviewContent> interviewContentList = analyzeHrInterviewRequest.getInterviewContentList();
        //预处理数据
        interviewContentList.remove(0);
        interviewContentList.remove(interviewContentList.size() - 1);
        //保存面试内容
        boolean update = hrInterviewContentService.lambdaUpdate()
                .eq(HrInterviewContent::getHrInterviewId, hrInterviewId)
                .set(HrInterviewContent::getInterviewContent, JSONUtil.toJsonStr(interviewContentList))
                .update();
        if (!update) {
            log.error("更新技术面试内容失败");
            throw new BusinessException(ErrorCode.PARAMS_ERROR, "更新技术面试内容失败");
        }
        // 保存当前面试数据
        //1 保存文本语速数据
        List<AudioSpeedEntry> audioSpeeds = getAudioSpeeds.getAudioSpeeds(userId);
        HrInterviewContent hrInterviewContent = new HrInterviewContent();
        hrInterviewContent.setSpeechRate(JSONUtil.toJsonStr(audioSpeeds));
        //2. 保存音频情感数据
        List<String> emotions = getAudioEmotion.getAllEmotions(userId);
        hrInterviewContent.setAudioEmotion(JSONUtil.toJsonStr(emotions));
        //3. 保存面部动作数据
        List<FaceActionManager.FaceAction> faceActions = faceActionManager.getFaceActions(userId);
        hrInterviewContent.setFacialActions(JSONUtil.toJsonStr(faceActions));
        //清空面部动作数据
        faceActionManager.clearUserData(userId.toString());
        //4. 保存躯体动作数据
        List<BodyActionManager.BodyAction> bodyActions = bodyActionManager.getBodyActions(userId);
        hrInterviewContent.setBodyMovements(JSONUtil.toJsonStr(bodyActions));
        //清空躯体动作数据
        bodyActionManager.clearUserData(userId.toString());
        //5. 保存面部情感数据
        List<String> faceEmotionStorageEmotions = faceEmotionManager.getEmotions(userId);
        hrInterviewContent.setMicroExpression(JSONUtil.toJsonStr(faceEmotionStorageEmotions));
        //清空面部情感数据
        faceEmotionManager.clearEmotions(userId);
        //6. 保存压力数据
        List<String> stress = stressManager.getStress(userId);
        hrInterviewContent.setStress(JSONUtil.toJsonStr(stress));
        //清空用户压力数据
        stressManager.clearStress(userId);

        //存储分析数据
        boolean update1 = hrInterviewContentService.lambdaUpdate()
                .eq(HrInterviewContent::getHrInterviewId, hrInterviewId)
                .set(HrInterviewContent::getSpeechRate, hrInterviewContent.getSpeechRate())
                .set(HrInterviewContent::getAudioEmotion, hrInterviewContent.getAudioEmotion())
                .set(HrInterviewContent::getFacialActions, hrInterviewContent.getFacialActions())
                .set(HrInterviewContent::getBodyMovements, hrInterviewContent.getBodyMovements())
                .set(HrInterviewContent::getMicroExpression, hrInterviewContent.getMicroExpression())
                .set(HrInterviewContent::getStress, hrInterviewContent.getStress())
                .update();
        if (!update1) throw new BusinessException(ErrorCode.OPERATION_ERROR, "保存面试数据失败");

        // 更新面试状态
        lambdaUpdate()
                .eq(HrInterview::getId, analyzeHrInterviewRequest.getHrInterviewId())
                .set(HrInterview::getInterviewStatus, AnalyzeStatusEnum.ANALYZING.getValue())
                .update();

        // 异步分析hr面试结果，并修改状态，保存到数据库
        CompletableFuture.runAsync(() -> {
            HrInterviewAnalysisData hrInterviewAnalysisData = null;
            try {
                // 调用hr分析工作流分析hr面试结果
                hrInterviewAnalysisData = HrInterviewAnalyze.analyzeHrInterview(userId, hrInterviewId);
            } catch (Exception e) {
                throw new BusinessException(ErrorCode.PARAMS_ERROR, "分析HR面试结果失败" + e.getMessage());
            }
            // 创建结果对象
            HrInterviewAnalyzeResult hrInterviewAnalyzeResult = new HrInterviewAnalyzeResult();

            hrInterviewAnalyzeResult.setHrInterviewId(hrInterviewId);

            // 设置 questionList（存储 JSON 字符串）
            String questionListJson = JSONUtil.toJsonStr(hrInterviewAnalysisData.getMultimodalAnalysis().getQuestionList());
            hrInterviewAnalyzeResult.setQuestionList(questionListJson);

            hrInterviewAnalyzeResult.setOverallMultimodalSummary(hrInterviewAnalysisData.getMultimodalAnalysis().getOverallMultimodalSummary());

            // 设置 communicationAbility（沟通表达能力）
            String communicationAbilityJson = JSONUtil.toJsonStr(hrInterviewAnalysisData.getCommunicationAbility());
            hrInterviewAnalyzeResult.setCommunicationAbility(communicationAbilityJson);

            //多模态评分
            Double totalScore = pythonApi.interviewMultimodalScoring(hrInterviewContent, userId, python_base_url_http + "/multimodal/scoring");
            hrInterviewAnalyzeResult.setTotalScore(totalScore.intValue());

            //设置分数列表
            hrInterviewAnalyzeResult.setScores(JSONUtil.toJsonStr(hrInterviewAnalysisData.getScores()));

            // 保存hr面试分析结果到数据库
            hrInterviewAnalyzeResultService.save(hrInterviewAnalyzeResult);

            //查看是否为全流程面试（回写hr面试分析结果id）
            if (isFull) {
                fullProcessAnalyzeResultService.lambdaUpdate()
                        .eq(FullProcessAnalyzeResult::getFullInterviewId, fullInterviewId)
                        .set(FullProcessAnalyzeResult::getHrInterviewAnalysisId, hrInterviewAnalyzeResult.getId())
                        .update();
            }

            //修改Hr面试状态(已完成)
            lambdaUpdate()
                    .eq(HrInterview::getId, hrInterviewId)
                    .set(HrInterview::getInterviewStatus, AnalyzeStatusEnum.COMPLETED.getValue())
                    .set(HrInterview::getHrInterviewResultId, hrInterviewAnalyzeResult.getId())
                    .update();
        }).exceptionally(ex -> {
            log.error("分析HR面试结果失败", ex);
            return null;
        });

        // 清空redis中的分析数据
        deleteAudioEmotion.deleteAllEmotions(userId);
        deleteAudioSpeed.deleteAllSpeedRecords(userId);
    }

    /**
     * 生成hr面试记录
     *
     * @param userId
     * @param position
     * @param positionName
     * @param techFieldName
     * @param companyId
     * @param resumeId
     * @param interviewerGender
     * @param languageMode
     * @param interviewerType
     * @param isFull
     * @param fullInterviewId
     * @return
     */
    @Override
    public Long generateHrInterview(Long userId, Position position, String positionName, String techFieldName, Long companyId, Long resumeId, String interviewerGender, String languageMode, String interviewerType, boolean isFull, Long fullInterviewId) {
        String company = companyService.getById(companyId).getName();

        //生成HR面试记录
        HrInterview hrInterview = new HrInterview();
        hrInterview.setResumeId(resumeId);
        hrInterview.setTechField(techFieldName);
        hrInterview.setPosition(positionName);
        hrInterview.setCompany(company);
        hrInterview.setLanguage(languageMode);
        hrInterview.setInterviewer(interviewerGender);
        hrInterview.setInterviewerType(interviewerType);
        hrInterview.setUserId(userId);
        hrInterview.setInterviewStatus(AnalyzeStatusEnum.UNFINISHED.getValue());
        //判断是否为全流程面试
        if (isFull) {
            hrInterview.setIsFull(IsFullInterviewEnum.FULL_INTERVIEW.getValue());
        } else {
            hrInterview.setIsFull(IsFullInterviewEnum.IS_NOT_FULL_INTERVIEW.getValue());
        }
        save(hrInterview);

        //是否为全流程面试(回写hr面id)
        if (isFull) {
            System.out.println("hr面id:" + hrInterview.getId());
            System.out.println("全流程面id:" + fullInterviewId);
            fullProcessInterviewService.lambdaUpdate()
                    .eq(FullProcessInterview::getId, fullInterviewId)
                    .set(FullProcessInterview::getHrInterviewId, hrInterview.getId())
                    .update();
        }

        //生成面试内容数据
        HrInterviewContent hrInterviewContent = new HrInterviewContent();
        hrInterviewContent.setHrInterviewId(hrInterview.getId());
        hrInterviewContent.setUserId(userId);
        hrInterviewContent.setInterviewContent("");
        hrInterviewContentService.save(hrInterviewContent);
        return hrInterview.getId();
    }

    /**
     * 删除hr面试记录和相关信息
     *
     * @param hrInterviewId
     * @param request
     * @return
     */
    @Override
    public boolean deleteHrInterview(Long hrInterviewId, HttpServletRequest request) {
        //开启方法事务
        transactionTemplate.execute(status -> {
            try {
                // 删除hr面记录
                removeById(hrInterviewId);

                // 删除hr面内容
                hrInterviewContentService.lambdaUpdate()
                        .eq(HrInterviewContent::getHrInterviewId, hrInterviewId)
                        .remove();

                // 删除hr面分析结果
                hrInterviewAnalyzeResultService.lambdaUpdate()
                        .eq(HrInterviewAnalyzeResult::getHrInterviewId, hrInterviewId)
                        .remove();

            } catch (Exception e) {
                throw new BusinessException(ErrorCode.OPERATION_ERROR, "删除hr面记录相关信息失败，id为::" + hrInterviewId + "，报错信息" + e.getMessage());
            }
            return null;
        });
        return true;
    }
}




